From 7125cdc5ff3ea398de22c7135306a53a74d304e6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 12 Jan 2014 22:06:59 -0500 Subject: [PATCH] X11: Support keyboard-initiated move and resize operations The EWMH defines _NET_WM_MOVERESIZE_SIZE_KEYBOARD and _NET_WM_MOVERESIZE_MOVE_KEYBOARD for operations that are not initiated by a button-press event. Allow using these by passing a button of 0 to gdk_window_begin_move/resize_drag. --- gdk/gdkwindow.c | 8 ++-- gdk/x11/gdkwindow-x11.c | 91 ++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 45 deletions(-) diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index 0f59c56f24..e613d9bbd8 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -10205,7 +10205,7 @@ gdk_window_set_functions (GdkWindow *window, * @window: a toplevel #GdkWindow * @edge: the edge or corner from which the drag is started * @device: the device used for the operation - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time()) @@ -10234,7 +10234,7 @@ gdk_window_begin_resize_drag_for_device (GdkWindow *window, * gdk_window_begin_resize_drag: * @window: a toplevel #GdkWindow * @edge: the edge or corner from which the drag is started - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time()) @@ -10266,7 +10266,7 @@ gdk_window_begin_resize_drag (GdkWindow *window, * gdk_window_begin_move_drag_for_device: * @window: a toplevel #GdkWindow * @device: the device used for the operation - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag @@ -10295,7 +10295,7 @@ gdk_window_begin_move_drag_for_device (GdkWindow *window, /** * gdk_window_begin_move_drag: * @window: a toplevel #GdkWindow - * @button: the button being used to drag + * @button: the button being used to drag, or 0 for a keyboard-initiated drag * @root_x: root window X coordinate of mouse click that began the drag * @root_y: root window Y coordinate of mouse click that began the drag * @timestamp: timestamp of mouse click that began the drag diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 186b8dfdb5..22252768fc 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -4760,8 +4760,8 @@ wmspec_moveresize (GdkWindow *window, { GdkDisplay *display = GDK_WINDOW_DISPLAY (window); - /* Release passive grab */ - gdk_device_ungrab (device, timestamp); + if (button != 0) + gdk_device_ungrab (device, timestamp); /* Release passive grab */ GDK_X11_DISPLAY (display)->wm_moveresize_button = button; wmspec_send_message (display, window, root_x, root_y, direction, button); @@ -4778,48 +4778,51 @@ wmspec_resize_drag (GdkWindow *window, { gint direction; - /* Let the compiler turn a switch into a table, instead - * of doing the table manually, this way is easier to verify. - */ - switch (edge) - { - case GDK_WINDOW_EDGE_NORTH_WEST: - direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; - break; + if (button == 0) + direction = _NET_WM_MOVERESIZE_SIZE_KEYBOARD; + else + switch (edge) + { + /* Let the compiler turn a switch into a table, instead + * of doing the table manually, this way is easier to verify. + */ + case GDK_WINDOW_EDGE_NORTH_WEST: + direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; + break; - case GDK_WINDOW_EDGE_NORTH: - direction = _NET_WM_MOVERESIZE_SIZE_TOP; - break; + case GDK_WINDOW_EDGE_NORTH: + direction = _NET_WM_MOVERESIZE_SIZE_TOP; + break; - case GDK_WINDOW_EDGE_NORTH_EAST: - direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; - break; + case GDK_WINDOW_EDGE_NORTH_EAST: + direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; + break; - case GDK_WINDOW_EDGE_WEST: - direction = _NET_WM_MOVERESIZE_SIZE_LEFT; - break; + case GDK_WINDOW_EDGE_WEST: + direction = _NET_WM_MOVERESIZE_SIZE_LEFT; + break; - case GDK_WINDOW_EDGE_EAST: - direction = _NET_WM_MOVERESIZE_SIZE_RIGHT; - break; + case GDK_WINDOW_EDGE_EAST: + direction = _NET_WM_MOVERESIZE_SIZE_RIGHT; + break; - case GDK_WINDOW_EDGE_SOUTH_WEST: - direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; - break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; + break; - case GDK_WINDOW_EDGE_SOUTH: - direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM; - break; + case GDK_WINDOW_EDGE_SOUTH: + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM; + break; - case GDK_WINDOW_EDGE_SOUTH_EAST: - direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; - break; + case GDK_WINDOW_EDGE_SOUTH_EAST: + direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; + break; - default: - g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", - edge); - return; - } + default: + g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!", + edge); + return; + } wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp); } @@ -5036,7 +5039,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event) impl = GDK_WINDOW_IMPL_X11 (mv_resize->moveresize_window->impl); - button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1); + if (mv_resize->moveresize_button != 0) + button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1); switch (event->xany.type) { @@ -5330,14 +5334,19 @@ gdk_x11_window_begin_move_drag (GdkWindow *window, gint root_y, guint32 timestamp) { - if (GDK_WINDOW_DESTROYED (window) || - !WINDOW_IS_TOPLEVEL (window)) + gint direction; + + if (GDK_WINDOW_DESTROYED (window) || !WINDOW_IS_TOPLEVEL (window)) return; + if (button == 0) + direction = _NET_WM_MOVERESIZE_MOVE_KEYBOARD; + else + direction = _NET_WM_MOVERESIZE_MOVE; + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE"))) - wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, - device, button, root_x, root_y, timestamp); + wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp); else emulate_move_drag (window, device, button, root_x, root_y, timestamp); } -- 2.30.2